package com.mygame.game_server.rank;

import com.alibaba.fastjson.JSONObject;
import com.mygame.game_server.async.AsyncOperationProcessor;
import com.mygame.game_server.async.IAsyncOperation;
import com.mygame.game_server.util.RedisUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Tuple;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.function.Function;

/**
 * 排序服务
 */
public class RankService {

    private final static Logger logger = LoggerFactory.getLogger(RankService.class);

    /**
     * 实例化
     */
    static private final RankService _instance = new RankService();

    private RankService() {

    }

    /**
     * 获取单例对象
     * @return
     */
    static public RankService getInstance() {
        return _instance;
    }

    /**
     * 获取排行榜
     * @param callback
     */
    public void getRank(Function<List<RankItem>,Void> callback) {

        if (null == callback) {
            return;
        }

        AsyncOperationProcessor.getInstance().process(new AsyncGetRank() {
            @Override
            public void doFinish() {
                callback.apply(this.getRankItemList());
            }
        });
    }

    public void refreshRank(int winnerId,int loserId) {
        if (winnerId <= 0 || loserId <= 0) {
            return;
        }

        try (Jedis jedis = RedisUtil.getJedis()) {
            jedis.hincrBy("User_" + winnerId,"Win",1);
            jedis.hincrBy("User_" + loserId,"Lose",1);

            String winStr = jedis.hget("User_" + winnerId,"Win");
            int winNum = Integer.parseInt(winStr);

            jedis.zadd("Rank",winNum,String.valueOf(winnerId));
        }catch (Exception e) {
            logger.error(e.getMessage(),e);
        }
    }

    /**
     * 异步方式获取排行榜
     */
    static private class AsyncGetRank implements IAsyncOperation {
        /**
         * 排名列表
         */
        private List<RankItem> _rankItemList;

        List<RankItem> getRankItemList () {
            return _rankItemList;
        }

        @Override
        public void doAsync() {
            try (Jedis jedis = RedisUtil.getJedis()) {
                //倒叙拿10个
                //by则是key范围内倒叙拿
                Set<Tuple> valSet = jedis.zrevrangeWithScores("Rank",0,9);

                List<RankItem> rankItems = new ArrayList<RankItem>();
                int i = 0;
                for (Tuple tuple : valSet) {
                    if (null == tuple) {
                        continue;
                    }
                    int userId =  Integer.parseInt(tuple.getElement());
                    //获取用户信息
                    String jsonStr = jedis.hget("User_" + userId,"BasicInfo");

                    if (null == jsonStr) {
                        continue;
                    }

                    RankItem newItem = new RankItem();
                    newItem.rankId = ++i;
                    newItem.userId = userId;
                    newItem.win = (int) tuple.getScore();

                    JSONObject jsonObject = JSONObject.parseObject(jsonStr);
                    newItem.userName = jsonObject.getString("userName");
                    newItem.heroAvatar = jsonObject.getString("heroAvatar");
                    rankItems.add(newItem);

                }

                _rankItemList = rankItems;
            } catch (Exception ex) {
                logger.error(ex.getMessage(),ex);
            }
        }
    }
}
